/* A simple server in the internet domain using TCP
   The port number is passed as an argument */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <bcm2835.h>
#include "BcmLib.h"

static uint8_t v1CsPins[] = {RPI_GPIO_P1_07, RPI_GPIO_P1_11, RPI_GPIO_P1_12, // 4,17,18
                      RPI_GPIO_P1_13, RPI_GPIO_P1_15, RPI_GPIO_P1_16, // 21,22,23
                      RPI_GPIO_P1_18, RPI_GPIO_P1_22};                // 24,25

static uint8_t v2CsPins[] = {RPI_V2_GPIO_P1_07, RPI_V2_GPIO_P1_11, RPI_V2_GPIO_P1_12,
                      RPI_V2_GPIO_P1_13, RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_16,
                      RPI_V2_GPIO_P1_18, RPI_V2_GPIO_P1_22};



void error(const char *msg)
{
    perror(msg);
    exit(1);
}

int main(int argc, char *argv[])
{
  
  int sockfd, newsockfd, portno;
  socklen_t clilen;
  char buffer[25];
  char response[24];
  struct sockaddr_in serv_addr, cli_addr;
  if (argc < 2) {
    fprintf(stderr,"ERROR, no port provided\n");
    exit(1);
  }
  
  
  sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if (sockfd < 0) 
    error("ERROR opening socket");
  bzero((char *) &serv_addr, sizeof(serv_addr));
  portno = atoi(argv[1]);
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = INADDR_ANY;
  serv_addr.sin_port = htons(portno);
  
  if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
    error("ERROR on binding");
  listen(sockfd,5);
  clilen = sizeof(cli_addr);
     
  while (1) {    
    printf("Waiting for a client to connect to...\n");
    newsockfd = accept(sockfd, 
		       (struct sockaddr *) &cli_addr, 
		       &clilen);
    if (newsockfd < 0) 
      error("ERROR on accept");
      
    if (initMySpi(v1CsPins, sizeof(v1CsPins)))
      error("ERROR on init SPI");
    
    while (1) {
      int n;
      bzero(buffer,25);
      n = read(newsockfd,buffer,25);
      if (n < 0) 
        error("read");
      if (n==0) {
	      printf("Closed Socket\n");
	      break;
      } else {
        mySpiTransfer(&(buffer[1]), response, 24, v1CsPins[buffer[0]]);
        n= write(newsockfd,response,24);
      }
    }
    close(newsockfd);
    bcm2835_spi_end();
    bcm2835_close();
  }
  close(sockfd);
  return 0; 
}
